package io.renren.common.utils;

import io.renren.common.exception.RRException;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static io.renren.common.utils.Constant.*;

public class MvsUtils {

    /**
     * 计算滞纳金
     * @param deadline 缴费截止时间
     * @param fineAmount 罚金
     * @return 滞纳金
     */
    public static BigDecimal calculateOverDueFee(Date deadline, BigDecimal fineAmount) {
        LocalDate localDate = deadline.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        long dayNumber = ChronoUnit.DAYS.between(localDate, LocalDate.now());
        if (dayNumber < 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal overDueFee = BigDecimal.ZERO;
        //1. 0-15天
        long firstPhaseDays = Math.min(dayNumber, 15);
        overDueFee = overDueFee.add(fineAmount.multiply(RATE_FIRST_15_DAYS).multiply(new BigDecimal(firstPhaseDays)));
        //2. 如果超过15天，15-30
        if (dayNumber > 15) {
            long secondPhaseDays = Math.min(dayNumber - 15, 15);
            overDueFee = overDueFee.add(fineAmount.multiply(RATE_15_TO_30_DAYS).multiply(new BigDecimal(secondPhaseDays)));
        }
        //3. 如果超过30天，30以后
        if (dayNumber > 30) {
            long thirdPhaseDays = dayNumber - 30;
            overDueFee = overDueFee.add(fineAmount.multiply(RATE_OVER_30_DAYS).multiply(new BigDecimal(thirdPhaseDays)));
        }
        return overDueFee;
    }

    /**
     * 检查日期范围是否合法
     */
    public static void checkDate(LocalDate start, LocalDate end) {
        if (start.isAfter(LocalDate.now())) {
            throw new RRException("开始日期不能是今天以后的日期");
        }
        if (start.isAfter(end)) {
            throw new RRException("开始日期不能再结束日期之后");
        }
    }

    /**
     * 根据日期范围和数据库数据统计每日的数据
     * @param start 开始日期
     * @param end 结束日期
     * @param dbDataList 数据库数据
     * @return Map
     */
    public static Map<String, Collection<?>> getStatisticByDateRange(LocalDate start, LocalDate end, List<Map<String, ?>> dbDataList) {
        // 补充缺少的日期
        List<LocalDate> dateRange = IntStream.rangeClosed(0, (int) (end.toEpochDay() - start.toEpochDay()))
                .mapToObj(start::plusDays).collect(Collectors.toList());
        Map<String, BigDecimal> dataMap = new TreeMap<>();
        dateRange.forEach(date -> dataMap.put(date.toString(), BigDecimal.ZERO));
        dbDataList.forEach(map -> dataMap.put(map.get("date").toString(), new BigDecimal(map.get("number").toString())));

        // 补充完成将其转换为两个List
        Map<String, Collection<?>> map = new HashMap<>();
        map.put("dateList", dataMap.keySet());
        map.put("numberList", dataMap.values());
        return map;
    }

}
